#pragma once

#include "base_call_agent.hpp"
#include "peer_connection_wrapper.hpp"
#include "ws_msg_dispatcher.hpp"
#include "api/p2pms_common.hpp"
#include "p2pms_log.hpp"
#include "message.hpp"

#include "api/peer_connection_interface.h"
#include "rtc_base/thread.h"

#include <nlohmann/json.hpp>
#include <future>

namespace p2pms
{

class P2PCallAgent : public BaseCallAgent
                   , public PeerConnectionWrapper::IPeerConnectionHandler
{
public:
	// 使用状态机来管理复杂的协商过程，取代多个布尔标志位。
	enum class NegotiationState {
		kIdle,          // 空闲，未开始协商
		kCreatingOffer, // 作为呼叫方，正在创建 Offer
		kWaitingForAnswer, // 已发送 Offer，等待对端的 Answer
		kProcessingOffer, // 作为被叫方，已收到 Offer，正在处理并创建 Answer
		kStable         // 协商完成，连接稳定
	};

	P2PCallAgent(CallRole role, 
		const std::string& user_id,
		IPcFactoryPtr factory,
		ICallHandler* handler, 
		rtc::Thread* sdk_thread, 
		std::shared_ptr<IMsgDispatcher> dispatcher);
	~P2PCallAgent() override;

public:
	// 公共接口保持不变
	ErrCode Init() override;
	ErrCode MakeCall(const std::string& callee_id) override;
	ErrCode IncomingCall(const CallMakeNotifyData& notify_data) override;
	void TerminateCall() override;
	ErrCode StartPublish(const MediaInfo& media) override;
	ErrCode StopPublish(const MediaInfo& media) override;
	ErrCode StartSubscribe(const std::string& user_id, const MediaInfo& media) override;
	ErrCode StopSubscribe(const std::string& user_id, const MediaInfo& media) override;
	void OnTimer() override;

private:
	typedef rtc::scoped_refptr<webrtc::MediaStreamInterface> MediaStreamSP;
	typedef rtc::scoped_refptr<webrtc::AudioSourceInterface> AudioSourceSP;
	typedef rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> VideoSourceSP;
	typedef rtc::scoped_refptr<webrtc::RtpTransceiverInterface> RtpTransceiverSP;
	typedef rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> MediaStreamTrackSP;

	struct PubMedia
	{
		MediaInfo media; // 媒体信息
		VideoSourceSP video_source; // 保存视频源，以保证视频源在SDK线程销毁
		AudioSourceSP audio_source;
	};

	struct SubMedia
	{
		std::string user_id; // 发布者ID
		MediaInfo media;     // 媒体信息
		std::string track_id;
	};

private:
	// --- IPeerConnectionHandler 实现 ---
    void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) override;
    void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) override;
    void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) override;
    void OnAddTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
		const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>& streams) override;
    void OnRemoveTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) override;
    void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override;
    void OnRenegotiationNeeded() override;

	// --- 核心协商逻辑 ---
	// 这些方法取代了旧的、分散的回调处理函数
	void StartNegotiationAsOfferer();
	void HandleRemoteAnswer(const std::string& sdp);
	void HandleRemoteOffer(const std::string& rid, const std::string& sdp);
	void SendSdpToServer(const std::string& rid, webrtc::SdpType type, const std::string& sdp);

	// --- 消息处理器 ---
	void OnCallMakeRes(const Message& msg, CBType cbt);
	void OnCallEndNotify(const Message& msg, CBType cbt);
	void OnCallEndRes(const Message& msg, CBType cbt);
	void OnCandidateNotify(const Message& msg, CBType cbt);
	void OnNegotiateReq(const Message& msg, CBType cbt);
	void OnNegotiateRes(const Message& msg, CBType cbt);
	void OnStartPublishRes(const Message& msg, CBType cbt);
	void OnStopPublishRes(const Message& msg, CBType cbt);
	void OnStopPublishNotify(const Message& msg, CBType cbt);
	void OnStartSubscribeRes(const Message& msg, CBType cbt);
	void OnStopSubscribeRes(const Message& msg, CBType cbt);
	void OnStartPublishNotify(const Message& msg, CBType cbt);
	void OnStartProduceNotify(const Message& msg, CBType cbt);

	// --- 内部辅助函数 ---
	bool CreatePeerConnection();
	void ClosePeerConnection();
	void RegisterMsgHandlers();
	void UnregisterMsgHandlers();
	void CallStateChanged(CallState state);
	void PostTaskToSdkThread(std::function<void()> task);
	bool ParseNegotiateData(const nlohmann::json& data, P2PNegotiateReqData& nrd);
	void StartProducing(const MediaInfo& media);
	bool FindSubMediaByTrackId(const std::string& track_id, SubMedia& media);
	bool FindSubMediaByMediaId(const std::string& media_id, SubMedia& media);
	MediaStreamTrackSP CreateTrackFromMedia(const MediaInfo& media);
	bool CreateDefaultTransceivers();
	void ApplyPendingRemoteCandidates();
	RtpTransceiverSP FindTransceiverByKind(const std::string& media_type);
	void UpdateSubMediaTrackId(const std::string& msid, const std::string& track_id);

private:
	rtc::Thread* m_sdk_thread = nullptr;
	std::shared_ptr<IMsgDispatcher> m_dispatcher;
	ICallHandler* m_call_handler = nullptr;
	IPcFactoryPtr m_pc_factory = nullptr;

	// 使用 PeerConnectionWrapper 替代原始的 PeerConnection
	std::unique_ptr<PeerConnectionWrapper> m_pc_wrapper;

	// 使用单一的状态机变量
	NegotiationState m_neg_state = NegotiationState::kIdle;

	bool m_is_negotiating = false;

	// 用于存储远端 ICE Candidate，直到 RemoteDescription 被设置
	std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> m_pending_remote_candidates;

	std::map<std::string, PubMedia> m_pub_medias;
	std::map<std::string, SubMedia> m_sub_medias;
};

} // namespace p2pms